/*
 * Copyright 2008-2009 Daniel Cachapa <cachapa@gmail.com>
 * 
 * This program is distributed under the terms of the GNU General Public Licence Version 3
 * The licence can be read in its entirety in the LICENSE.txt file accompaning this source code,
 * or at: http://www.gnu.org/copyleft/gpl.html
 * 
 * This file is part of WeightWatch.
 *
 * WeightWatch is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * WeightWatch is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the WeightWatch source code. If not, see
 * <http://www.gnu.org/licenses/>.
 */

package net.cachapa.weightwatch.ui.components;

import com.sun.lwuit.Button;
import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Container;
import com.sun.lwuit.Dialog;
import com.sun.lwuit.Display;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Label;
import com.sun.lwuit.Painter;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.events.DataChangedListener;
import com.sun.lwuit.geom.Rectangle;
import com.sun.lwuit.layouts.FlowLayout;
import net.cachapa.weightwatch.util.MyDate;

public class DateField extends Button implements ActionListener {
	private Component parent;
	private long time;
	private DateSelector dateSelector;
	private Command setCommand;
	private Command cancelCommand;
	private DataChangedListener dataChangedListener = null;

	public DateField(Component parent) {
		this.parent = parent;
		this.time = System.currentTimeMillis();
		this.setAlignment(CENTER);
		MyDate date = new MyDate(this.time);
		this.setText(date.toShortString());
		
		this.setCommand = new Command("ok");
		this.cancelCommand = new Command("cancel");
		
		this.dateSelector = new DateSelector(this.time);
		this.dateSelector.getContentPane().getStyle().setBgTransparency(0);
		this.dateSelector.addCommand(setCommand);
		this.dateSelector.setDefaultCommand(setCommand);
		this.dateSelector.addCommand(cancelCommand);
		this.dateSelector.setBackCommand(cancelCommand);
		
		this.addActionListener(this);
	}

	public void addDataChangeListener(DataChangedListener dataChangedListener) {
		this.dataChangedListener = dataChangedListener;
	}

	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
		this.setText(new MyDate(time).toShortString());
		this.dateSelector.setTime(time);
	}

	public void actionPerformed(ActionEvent ae) {
		Command result = dateSelector.showDialog();
		
		if (result == setCommand) {
			this.time = dateSelector.getTime();
			this.setText(new MyDate(time).toShortString());
			parent.repaint(); // The size of the button might have changed
			if (dataChangedListener != null) {
				this.dataChangedListener.dataChanged(TOP, TOP);
			}
		}
		else if (result == cancelCommand) {
			// Do nothing
		}
	}
	
	private class DateSelector extends Dialog {
	private int day, month, year;
	private Label dayLabel, monthLabel, yearLabel;

	public DateSelector(long time) {
		MyDate date = new MyDate(time);
		this.setTitle("datefield_setdate");
		this.day = date.getDay();
		this.month = date.getMonth();
		this.year = date.getYear();
		
		this.getTitleStyle().setBgPainter(new Painter() {
			public void paint(Graphics g, Rectangle rect) {
				g.setColor(0x00222222);
				g.fillRoundRect(rect.getX(), rect.getY(),
					 rect.getSize().getWidth(), rect.getSize().getHeight(), 12, 12);
			}
		});
		
		this.getContentPane().setLayout(new FlowLayout(Component.CENTER));
		
		Container container = new Container();
		container.getStyle().setBgPainter(new Painter() {
			public void paint(Graphics g, Rectangle rect) {
				g.setColor(0x00333333);
				g.fillRoundRect(rect.getX(), rect.getY(),
					 rect.getSize().getWidth(), rect.getSize().getHeight(), 12, 12);
			}
		});
		
		this.dayLabel = new Label(this.day+"");
		this.dayLabel.setFocusable(true);
		
		this.monthLabel = new Label(date.getShortMonthName());
		this.monthLabel.setFocusable(true);
		
		this.yearLabel = new Label(this.year+"");
		this.yearLabel.setFocusable(true);
		
		container.addComponent(this.dayLabel);
		container.addComponent(this.monthLabel);
		container.addComponent(this.yearLabel);
		
		this.addComponent(container);
	}
	
	public long getTime() {
		return new MyDate(day, month, year).getTime();
	}
	
	public void setTime(long time) {
		MyDate date = new MyDate(time);
		this.day = date.getDay();
		this.month = date.getMonth();
		this.year = date.getYear();
		this.dayLabel.setText(this.day+"");
		this.monthLabel.setText(date.getShortMonthName());
		this.year = date.getYear();
		this.yearLabel.setText(this.year+"");
	}
	
	private void increaseValue() {
		int maxDays;
				
		if (dayLabel.hasFocus()) {
			this.day++;
			maxDays = MyDate.getDaysInMonth(month, year);
			if (this.day > maxDays) this.day = 1;
			dayLabel.setText(this.day+"");
		}
		
		else if (monthLabel.hasFocus()) {
			this.month++;
			if (this.month > 12) this.month = 1;
			maxDays = MyDate.getDaysInMonth(month, year);
			monthLabel.setText(MyDate.getShortMonthName(month));
			if (this.day > maxDays) {
				this.day = maxDays;
				dayLabel.setText(this.day+"");
			}
		}
		
		else if (yearLabel.hasFocus()) {
			this.year++;
			maxDays = MyDate.getDaysInMonth(month, year);
			yearLabel.setText(this.year+"");
			if (this.day > maxDays) {
				this.day = maxDays;
				dayLabel.setText(this.day+"");
			}
		}
		this.repaint();
	}

	private void decreaseValue() {
		int maxDays;
				
		if (dayLabel.hasFocus()) {
			this.day--;
			maxDays = MyDate.getDaysInMonth(month, year);
			if (this.day < 1) this.day = maxDays;
			dayLabel.setText(this.day+"");
		}
		
		else if (monthLabel.hasFocus()) {
			this.month--;
			if (this.month < 1) this.month = 12;
			maxDays = MyDate.getDaysInMonth(month, year);
			monthLabel.setText(MyDate.getShortMonthName(month));
			if (this.day > maxDays) {
				this.day = maxDays;
				dayLabel.setText(this.day+"");
			}
		}
		
		else if (yearLabel.hasFocus()) {
			this.year--;
			maxDays = MyDate.getDaysInMonth(month, year);
			yearLabel.setText(this.year+"");
			if (this.day > maxDays) {
				this.day = maxDays;
				dayLabel.setText(this.day+"");
			}
		}
		this.repaint();
	}

	public void keyPressed(int keyCode) {
		int k = Display.getInstance().getGameAction(keyCode);
		switch (k) {
			case Display.GAME_UP:
				increaseValue();
				break;

			case Display.GAME_DOWN:
				decreaseValue();
				break;
				
			default:
				super.keyPressed(keyCode);
		}
	}
	}
}
